use log::{error, info, warn};
use rust_i18n::t;
use tauri::AppHandle;

use crate::{
    backup::Game,
    config::{get_config, set_config},
    preclude::*,
};

pub async fn set_current_game(app: &AppHandle, game: Game) -> anyhow::Result<()> {
    info!(target:"rgsm::tray","Setting current quick backup game:{}",game.name);
    app.tray_by_id("tray_icon")
        .ok_or(anyhow::anyhow!("Cannot get tray"))?
        .set_title(Some(&game.name))?;
    let mut config = get_config().expect("Cannot get config");
    config.quick_action.quick_action_game = Some(game);
    set_config(&config).await.expect("Cannot set config");
    Ok(())
}

#[derive(Debug, PartialEq)]
pub enum QuickActionType {
    Timer,
    Tray,
    Hotkey,
}

impl QuickActionType {
    fn generate_describe(&self) -> String {
        match &self {
            QuickActionType::Timer => String::from("Auto Backup (Timer)"),
            QuickActionType::Tray => String::from("Quick Backup (Tray)"),
            QuickActionType::Hotkey => String::from("Quick Backup (Hotkey)"),
        }
    }
}

pub async fn quick_apply(t: QuickActionType) {
    info!(target:"rgsm::quick_action", "Auto apply triggered: {:#?}", t.generate_describe());
    let game = get_quick_action_game();

    // 检查游戏是否已选择
    let game = match game {
        Some(game) => game,
        None => {
            show_no_game_selected_error();
            return;
        }
    };

    info!(target:"rgsm::quick_action", "Quick apply game: {:#?}", game);

    // 执行恢复操作
    let result = async {
        let newest_date = game
            .get_game_snapshots_info()?
            .backups
            .last()
            .ok_or(BackupError::NoBackupAvailable)?
            .date
            .clone();
        game.restore_snapshot(&newest_date, None)
    }
    .await;

    // 处理结果
    match result {
        Err(e) => {
            error!(target:"rgsm::quick_action", "Quick apply failed: {:#?}", &e);
            show_notification(
                t!("backend.tray.error"),
                format!("{:#?}\n{:#?}", t!("backend.tray.find_error_detail"), e),
            );
        }
        Ok(_) => {
            show_notification(
                t!("backend.tray.success"),
                format!(
                    "{:#?} {} {}",
                    game.name,
                    t!("backend.tray.quick_apply"),
                    t!("backend.tray.success")
                ),
            );
        }
    }
}

pub async fn quick_backup(t: QuickActionType) {
    info!(target:"rgsm::quick_action", "Auto backup triggered: {:#?}", t.generate_describe());
    let show_info = get_config()
        .expect("Cannot get config")
        .settings
        .prompt_when_auto_backup;

    // 检查游戏是否已选择
    let game = match get_quick_action_game() {
        Some(game) => game,
        None => {
            show_no_game_selected_error();
            return;
        }
    };

    // 执行备份操作
    let result = game.create_snapshot(&t.generate_describe()).await;

    // 处理结果
    match result {
        Err(e) => {
            error!(target:"rgsm::quick_action", "Quick backup failed: {:#?}", &e);
            show_notification(
                t!("backend.tray.error"),
                format!("{:#?}\n{:#?}", t!("backend.tray.find_error_detail"), e),
            );
        }
        Ok(_) => {
            // 根据设置决定是否显示通知
            if !show_info && (t == QuickActionType::Timer) {
                // 设置中该选项控制是否在按间隔备份时发出通知
                // 若不启用，则不进行通知，其余情况则产生通知
                return;
            }
            show_notification(
                t!("backend.tray.success"),
                format!(
                    "{:#?} {} {}",
                    game.name,
                    t!("backend.tray.quick_backup"),
                    t!("backend.tray.success")
                ),
            );
        }
    }
}

fn show_no_game_selected_error() {
    warn!(target:"rgsm::quick_action", "No game selected, cannot quick backup/apply");
    show_notification(
        t!("backend.tray.error"),
        t!("backend.tray.no_game_selected"),
    );
}

pub fn get_quick_action_game() -> Option<Game> {
    get_config()
        .expect("Cannot get config")
        .quick_action
        .quick_action_game
        .clone()
}
